package link

import (
	"gitee.com/xinshortlink/internal/dto"
	"gitee.com/xinshortlink/internal/dto/resp"
	"gitee.com/xinshortlink/internal/service/link"
	"gitee.com/xinshortlink/internal/service/visitrecord"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
)

type Api struct {
	logger             *zap.Logger
	resp               *resp.Util
	service            *link.Service
	visitRecordService *visitrecord.Service
}

func NewApi(logger *zap.Logger, resp *resp.Util, service *link.Service, visitRecordService *visitrecord.Service) *Api {
	return &Api{
		logger:             logger,
		resp:               resp,
		service:            service,
		visitRecordService: visitRecordService,
	}
}

func (a *Api) Links(ctx *gin.Context) {
	req := &dto.FindLinkDTO{}
	if err := ctx.ShouldBindQuery(req); err != nil {
		a.resp.Resp(ctx, err, nil)
		return
	}

	links, err := a.service.Links(ctx.Request.Context(), req)
	a.resp.Resp(ctx, err, links)
}

func (a *Api) Create(ctx *gin.Context) {
	req := &dto.CreateLinkReq{}
	if err := ctx.ShouldBindJSON(req); err != nil {
		a.resp.Resp(ctx, err, nil)
		return
	}

	err := a.service.Create(ctx.Request.Context(), req)
	a.resp.Resp(ctx, err, nil)
}

func (a *Api) CreateBatch(ctx *gin.Context) {

}

func (a *Api) UpdateStatus(ctx *gin.Context) {
	req := &dto.UpdateStatusLinkReq{}
	if err := ctx.ShouldBindJSON(req); err != nil {
		a.resp.Resp(ctx, err, nil)
		return
	}

	err := a.service.UpdateStatus(ctx.Request.Context(), req.Id, req.Gid)
	a.resp.Resp(ctx, err, nil)
}

func (a *Api) Del(ctx *gin.Context) {
	req := &dto.DelLinkReq{}
	if err := ctx.ShouldBindQuery(req); err != nil {
		a.resp.Resp(ctx, err, nil)
		return
	}

	err := a.service.Del(ctx.Request.Context(), req.Id, req.Gid)
	a.resp.Resp(ctx, err, nil)
}

func (a *Api) Redirect(ctx *gin.Context) {
	req := &dto.RedirectReq{}
	if err := ctx.ShouldBindUri(req); err != nil {
		a.resp.Resp(ctx, err, nil)
	}

	redirectUrl, err := a.service.FindRedirectUrl(ctx.Request.Context(), req.ShortId)
	if err != nil {
		a.resp.Resp(ctx, err, nil)
		return
	}

	err = a.visitRecordService.CreateVisitRecord(ctx, req.ShortId) // 创建访问记录
	if err != nil {
		a.resp.Resp(ctx, err, nil)
		return
	}

	ctx.Redirect(http.StatusFound, redirectUrl)
}

// GetVisitRecord 获取短链接的访问记录
func (a *Api) GetVisitRecord(ctx *gin.Context) {
	req := &dto.VisitRecordReq{}
	if err := ctx.ShouldBindQuery(req); err != nil {
		a.resp.Resp(ctx, err, nil)
		return
	}

	records, err := a.visitRecordService.GetVisitRecord(ctx.Request.Context(), req)
	a.resp.Resp(ctx, err, records)
}
